
#include <exception>
#include <stdexcept>

#include <Wt/WColor>

#include "genetic_lego/LegoDescription.h"

using namespace std;

void LegoDescription::set_color( LegoDescription::LegoColor c )
{
  Wt::WColor clr;

  switch( c )
  {
    case kGreen:
      clr = Wt::darkGreen;
      break;
    case kYellow:
      clr = Wt::darkYellow;
      break;
    case kBlue:
      clr = Wt::darkBlue;
      break;
    case kRed:
      clr = Wt::darkRed;
      break;
    case kGrey:
      clr = Wt::darkGray;
      break;
    case kWhite:
      clr = Wt::lightGray;
      break;
    case kNumLegoColors:
      throw std::runtime_error( "LegoDescription::set_color(...): invalid lego color." );
      break;
  }//switch( color )

  color[0] = clr.red();
  color[1] = clr.green();
  color[2] = clr.blue();
}//void set_color(...)


Wt::WColor LegoDescription::penColor() const
{
  return Wt::WColor( color[0], color[1], color[2] );
  /*
  switch( color )
  {
    case kGreen:
      return Wt::darkGreen;
    case kYellow:
      return Wt::darkYellow;
    case kBlue:
      return Wt::darkBlue;
    case kRed:
      return Wt::darkRed;
    case kGrey:
      return Wt::darkGray;
    case kWhite:
      return Wt::lightGray;
    case kNumLegoColors:
      break;
  }//switch( color )

  throw std::runtime_error( "Invalid color" );
  return Wt::black;
  */
}//penColor()

Wt::WColor LegoDescription::fillColor() const
{
  return Wt::WColor( color[0], color[1], color[2] );

  /*
  switch( color )
  {
    case kGreen:
      return Wt::green;
    case kYellow:
      return Wt::yellow;
    case kBlue:
      return Wt::blue;
    case kRed:
      return Wt::red;
    case kGrey:
      return Wt::gray;
    case kWhite:
      return Wt::white;
    case kNumLegoColors:
      break;
  }//switch( color )

  throw std::runtime_error( "Invalid color" );
  return Wt::black;
  */
}


int LegoDescription::nrows() const
{
  return nrows( type );
}

int LegoDescription::ncolomuns() const
{
  return ncolomuns( type );
}

int LegoDescription::nrows( LegoDescription::LegoType type )
{
  switch( type )
  {
    case LegoDescription::k1x1:
    case LegoDescription::k2x1:
    case LegoDescription::k4x1:
      return 1;

    case LegoDescription::k2x2:
    case LegoDescription::k8x2:
    case LegoDescription::k4x2:
    case LegoDescription::k1x2:
      return 2;

    case LegoDescription::k2x4:
    case LegoDescription::k1x4:
      return 4;

    case LegoDescription::k2x8:
      return 8;

    case LegoDescription::kNumLegoTypes:
      break;
  }//switch( lego.type )

  throw std::runtime_error( "Invalid lego type" );
  return 1.0;
}//int nrows() const

int LegoDescription::ncolomuns( LegoDescription::LegoType type )
{
  switch( type )
  {
    case LegoDescription::k1x1:
    case LegoDescription::k1x4:
    case LegoDescription::k1x2:
      return 1;

    case LegoDescription::k2x2:
    case LegoDescription::k2x4:
    case LegoDescription::k2x8:
    case LegoDescription::k2x1:
      return 2;

    case LegoDescription::k4x2:
    case LegoDescription::k4x1:
      return 4;

    case LegoDescription::k8x2:
      return 8;

    case LegoDescription::kNumLegoTypes:
      break;
  }//switch( lego.type )

  throw std::runtime_error( "Invalid lego type" );
  return 1.0;
}//ncolomuns()

int LegoSceneDescription::widthInPixels() const
{
  return scene_width * pixels_per_cell;
}

int LegoSceneDescription::heightInPixels() const
{
  return scene_height * pixels_per_cell;
}


double LegoSceneDescription::xStartPosInPixels( const LegoDescription &lego ) const
{
  return (lego.pos_x-0.5) * pixels_per_cell;
}

double LegoSceneDescription::yStartPosInPixels( const LegoDescription &lego ) const
{
  return (lego.pos_y-0.5) * pixels_per_cell;
}


double LegoSceneDescription::legoWidthInPixels( const LegoDescription &lego ) const
{
  return static_cast<double>(pixels_per_cell) * lego.ncolomuns();
}//legoWidthInPixels(...)


double LegoSceneDescription::legoHeightInPixels( const LegoDescription &lego ) const
{
  return static_cast<double>(pixels_per_cell) * lego.nrows();
}//LegoSceneDescription::legoHeightInPixels
